Imports System.Xml
Imports Vestris.VMWareLib


Module BackupServer

    Sub BackupVM(ByVal VMXFile As String, ByVal UniqueID As String, ByVal DataStorePath As String)

        'Check VMX file still exists
        If My.Computer.FileSystem.FileExists(VMXFile) Then

            'update progress to suspending
            UpdateProgressBasic(UniqueID, "Suspending Server")

            'copy the files
            CopyServerFiles(VMXFile, UniqueID, DataStorePath)

        Else
            MessageToLog(Now() & " - " & "VMX file no longer exisits")
        End If

    End Sub

    Sub SuspendServer(ByVal VMXFile As String, ByVal DataStorePath As String)
        Dim cp As New VMCOMLib.VmConnectParams
        Dim server As New VMCOMLib.VmServerCtl
        Dim vm As New VMCOMLib.VmCtl

        Dim connectparams As String() = GetHostInfo()


        cp.Hostname = connectparams(0)
        cp.Port = connectparams(1)
        cp.Username = connectparams(2)
        cp.Password = connectparams(3)

        server.Connect(cp)
        vm.Connect(cp, DataStorePath)

        If vm.ExecutionState = VMCOMLib.VmExecutionState.vmExecutionState_On Then

            Try
                MessageToLog(Now() & " - " & "Before suspend power check 1...")

                vm.Suspend(VMCOMLib.VmPowerOpMode.vmPowerOpMode_TrySoft)


                MessageToLog(Now() & " - " & "Before suspend power check 2...")
                CheckServerStatus(VMXFile, DataStorePath)

            Catch ce As System.Runtime.InteropServices.COMException
                If ce.ErrorCode = Convert.ToInt32(VMCOMLib.VmErr.vmErr_TIMEOUT) Then
                    Do Until vm.Heartbeat = 0
                        System.Threading.Thread.Sleep(New TimeSpan(0, 0, 30))
                    Loop
                Else
                    MessageToLog(ce.Source & " " & ce.Message & " - " & ce.ErrorCode)
                End If
            Finally
                cp = Nothing
                server = Nothing
                vm = Nothing
            End Try
        End If

    End Sub

    Sub ResumeServer(ByVal VMXFile As String, ByVal DataStorePath As String)
        Dim cp As New VMCOMLib.VmConnectParams
        Dim server As New VMCOMLib.VmServerCtl
        Dim vm As New VMCOMLib.VmCtl
        Dim AnswerQuestions As Boolean = False
        Dim vmq As VMCOMLib.IVmQuestion = Nothing

        Dim connectparams As String() = GetHostInfo()

        cp.Hostname = connectparams(0)
        cp.Port = connectparams(1)
        cp.Username = connectparams(2)
        cp.Password = connectparams(3)

        server.Connect(cp)
        vm.Connect(cp, DataStorePath)
        Try
            MessageToLog(Now() & " - " & "Before resume power check...")
            CheckServerStatus(VMXFile, DataStorePath)

            If vm.ExecutionState = VMCOMLib.VmExecutionState.vmExecutionState_Suspended Then
                Try
                    vm.Start(VMCOMLib.VmPowerOpMode.vmPowerOpMode_TrySoft)
                Catch ce As System.Runtime.InteropServices.COMException
                    If vm.ExecutionState = VmExecutionState.vmExecutionState_Stuck And ce.ErrorCode = Convert.ToInt32(VmErr.vmErr_NEEDINPUT) Then
                        If vmq.Id = 1 Or vmq.Id = 3 Then
                            AnswerQuestions = True
                        End If
                    Else
                        MessageToLog(Now() & " - Error resuming server - " & vmq.Text & " - " & ce.Source & " - " & ce.Message & " - " & ce.ErrorCode)
                    End If
                End Try
            End If

            If AnswerQuestions = True Then
                Dim n As Integer = 1
                Do Until vm.ExecutionState = VmExecutionState.vmExecutionState_On Or n = 10
                    AnswerVM(VMXFile, DataStorePath)
                    n = n + 1
                Loop
            End If
        Catch ce As System.Runtime.InteropServices.COMException
            MessageToLog(ce.Source & " " & ce.Message & " - " & ce.ErrorCode)
        End Try
    End Sub

    Sub AnswerVM(ByVal VMXFile As String, ByVal DataStorePath As String)
        Try
            Dim cp As New VMCOMLib.VmConnectParams
            Dim server As New VMCOMLib.VmServerCtl
            Dim vm As New VMCOMLib.VmCtl
            Dim vmq As VMCOMLib.IVmQuestion = Nothing

            Dim connectparams As String() = GetHostInfo()

            cp.Hostname = connectparams(0)
            cp.Port = connectparams(1)
            cp.Username = connectparams(2)
            cp.Password = connectparams(3)

            server.Connect(cp)
            vm.Connect(cp, DataStorePath)

            If vm.ExecutionState = VmExecutionState.vmExecutionState_Stuck Then
                Try
                    vmq = vm.PendingQuestion
                    vm.AnswerQuestion(vmq, 1) 'choose no to not start with the device connected
                Catch ce As System.Runtime.InteropServices.COMException
                    MessageToLog(ce.Source & " " & ce.Message)
                End Try
            End If

        Catch ex As Exception
            MessageToLog(ex.Source & " " & ex.Message)
        End Try
       
    End Sub

    Sub CheckServerStatus(ByVal VMXFile As String, ByVal DataStorePath As String)
        Try
            Dim cp As New VMCOMLib.VmConnectParams
            Dim server As New VMCOMLib.VmServerCtl
            Dim vm As New VMCOMLib.VmCtl

            Dim connectparams As String() = GetHostInfo()

            cp.Hostname = connectparams(0)
            cp.Port = connectparams(1)
            cp.Username = connectparams(2)
            cp.Password = connectparams(3)

            server.Connect(cp)
            vm.Connect(cp, DataStorePath)

            If vm.ExecutionState <> VmExecutionState.vmExecutionState_On Then
                Try
                    MessageToLog(Now() & " - " & "The server does not seem to be powered on")
                    MessageToLog(Now() & " - Server state is " & vm.ExecutionState.ToString())
                Catch ex As Exception
                    MessageToLog(ex.Source & " " & ex.Message)
                Finally
                    cp = Nothing
                    server = Nothing
                    vm = Nothing
                End Try
            Else

            End If

        Catch ex As Exception
            MessageToLog(ex.Source & " " & ex.Message)
        End Try

    End Sub

End Module
